1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gio.DebugControllerDBus; 26 27 private import gio.Cancellable; 28 private import gio.DBusConnection; 29 private import gio.DBusMethodInvocation; 30 private import gio.DebugControllerIF; 31 private import gio.DebugControllerT; 32 private import gio.InitableIF; 33 private import gio.InitableT; 34 private import gio.c.functions; 35 public import gio.c.types; 36 private import glib.ConstructionException; 37 private import glib.ErrorG; 38 private import glib.GException; 39 private import gobject.ObjectG; 40 private import gobject.Signals; 41 private import std.algorithm; 42 43 44 /** 45 * #GDebugControllerDBus is an implementation of #GDebugController which exposes 46 * debug settings as a D-Bus object. 47 * 48 * It is a #GInitable object, and will register an object at 49 * `/org/gtk/Debugging` on the bus given as 50 * #GDebugControllerDBus:connection once it’s initialized. The object will be 51 * unregistered when the last reference to the #GDebugControllerDBus is dropped. 52 * 53 * This D-Bus object can be used by remote processes to enable or disable debug 54 * output in this process. Remote processes calling 55 * `org.gtk.Debugging.SetDebugEnabled()` will affect the value of 56 * #GDebugController:debug-enabled and, by default, g_log_get_debug_enabled(). 57 * default. 58 * 59 * By default, all processes will be able to call `SetDebugEnabled()`. If this 60 * process is privileged, or might expose sensitive information in its debug 61 * output, you may want to restrict the ability to enable debug output to 62 * privileged users or processes. 63 * 64 * One option is to install a D-Bus security policy which restricts access to 65 * `SetDebugEnabled()`, installing something like the following in 66 * `$datadir/dbus-1/system.d/`: 67 * |[<!-- language="XML" --> 68 * <?xml version="1.0"?> <!--*-nxml-*--> 69 * <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" 70 * "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> 71 * <busconfig> 72 * <policy user="root"> 73 * <allow send_destination="com.example.MyService" send_interface="org.gtk.Debugging"/> 74 * </policy> 75 * <policy context="default"> 76 * <deny send_destination="com.example.MyService" send_interface="org.gtk.Debugging"/> 77 * </policy> 78 * </busconfig> 79 * ]| 80 * 81 * This will prevent the `SetDebugEnabled()` method from being called by all 82 * except root. It will not prevent the `DebugEnabled` property from being read, 83 * as it’s accessed through the `org.freedesktop.DBus.Properties` interface. 84 * 85 * Another option is to use polkit to allow or deny requests on a case-by-case 86 * basis, allowing for the possibility of dynamic authorisation. To do this, 87 * connect to the #GDebugControllerDBus::authorize signal and query polkit in 88 * it: 89 * |[<!-- language="C" --> 90 * g_autoptr(GError) child_error = NULL; 91 * g_autoptr(GDBusConnection) connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); 92 * gulong debug_controller_authorize_id = 0; 93 * 94 * // Set up the debug controller. 95 * debug_controller = G_DEBUG_CONTROLLER (g_debug_controller_dbus_new (priv->connection, NULL, &child_error)); 96 * if (debug_controller == NULL) 97 * { 98 * g_error ("Could not register debug controller on bus: %s"), 99 * child_error->message); 100 * } 101 * 102 * debug_controller_authorize_id = g_signal_connect (debug_controller, 103 * "authorize", 104 * G_CALLBACK (debug_controller_authorize_cb), 105 * self); 106 * 107 * static gboolean 108 * debug_controller_authorize_cb (GDebugControllerDBus *debug_controller, 109 * GDBusMethodInvocation *invocation, 110 * gpointer user_data) 111 * { 112 * g_autoptr(PolkitAuthority) authority = NULL; 113 * g_autoptr(PolkitSubject) subject = NULL; 114 * g_autoptr(PolkitAuthorizationResult) auth_result = NULL; 115 * g_autoptr(GError) local_error = NULL; 116 * GDBusMessage *message; 117 * GDBusMessageFlags message_flags; 118 * PolkitCheckAuthorizationFlags flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE; 119 * 120 * message = g_dbus_method_invocation_get_message (invocation); 121 * message_flags = g_dbus_message_get_flags (message); 122 * 123 * authority = polkit_authority_get_sync (NULL, &local_error); 124 * if (authority == NULL) 125 * { 126 * g_warning ("Failed to get polkit authority: %s", local_error->message); 127 * return FALSE; 128 * } 129 * 130 * if (message_flags & G_DBUS_MESSAGE_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION) 131 * flags |= POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION; 132 * 133 * subject = polkit_system_bus_name_new (g_dbus_method_invocation_get_sender (invocation)); 134 * 135 * auth_result = polkit_authority_check_authorization_sync (authority, 136 * subject, 137 * "com.example.MyService.set-debug-enabled", 138 * NULL, 139 * flags, 140 * NULL, 141 * &local_error); 142 * if (auth_result == NULL) 143 * { 144 * g_warning ("Failed to get check polkit authorization: %s", local_error->message); 145 * return FALSE; 146 * } 147 * 148 * return polkit_authorization_result_get_is_authorized (auth_result); 149 * } 150 * ]| 151 * 152 * Since: 2.72 153 */ 154 public class DebugControllerDBus : ObjectG, DebugControllerIF, InitableIF 155 { 156 /** the main Gtk struct */ 157 protected GDebugControllerDBus* gDebugControllerDBus; 158 159 /** Get the main Gtk struct */ 160 public GDebugControllerDBus* getDebugControllerDBusStruct(bool transferOwnership = false) 161 { 162 if (transferOwnership) 163 ownedRef = false; 164 return gDebugControllerDBus; 165 } 166 167 /** the main Gtk struct as a void* */ 168 protected override void* getStruct() 169 { 170 return cast(void*)gDebugControllerDBus; 171 } 172 173 /** 174 * Sets our main struct and passes it to the parent class. 175 */ 176 public this (GDebugControllerDBus* gDebugControllerDBus, bool ownedRef = false) 177 { 178 this.gDebugControllerDBus = gDebugControllerDBus; 179 super(cast(GObject*)gDebugControllerDBus, ownedRef); 180 } 181 182 // add the DebugController capabilities 183 mixin DebugControllerT!(GDebugControllerDBus); 184 185 // add the Initable capabilities 186 mixin InitableT!(GDebugControllerDBus); 187 188 189 /** */ 190 public static GType getType() 191 { 192 return g_debug_controller_dbus_get_type(); 193 } 194 195 /** 196 * Create a new #GDebugControllerDBus and synchronously initialize it. 197 * 198 * Initializing the object will export the debug object on @connection. The 199 * object will remain registered until the last reference to the 200 * #GDebugControllerDBus is dropped. 201 * 202 * Initialization may fail if registering the object on @connection fails. 203 * 204 * Params: 205 * connection = a #GDBusConnection to register the debug object on 206 * cancellable = a #GCancellable, or %NULL 207 * 208 * Returns: a new #GDebugControllerDBus, or %NULL 209 * on failure 210 * 211 * Since: 2.72 212 * 213 * Throws: GException on failure. 214 * Throws: ConstructionException GTK+ fails to create the object. 215 */ 216 public this(DBusConnection connection, Cancellable cancellable) 217 { 218 GError* err = null; 219 220 auto __p = g_debug_controller_dbus_new((connection is null) ? null : connection.getDBusConnectionStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), &err); 221 222 if (err !is null) 223 { 224 throw new GException( new ErrorG(err) ); 225 } 226 227 if(__p is null) 228 { 229 throw new ConstructionException("null returned by new"); 230 } 231 232 this(cast(GDebugControllerDBus*) __p, true); 233 } 234 235 /** 236 * Stop the debug controller, unregistering its object from the bus. 237 * 238 * Any pending method calls to the object will complete successfully, but new 239 * ones will return an error. This method will block until all pending 240 * #GDebugControllerDBus::authorize signals have been handled. This is expected 241 * to not take long, as it will just be waiting for threads to join. If any 242 * #GDebugControllerDBus::authorize signal handlers are still executing in other 243 * threads, this will block until after they have returned. 244 * 245 * This method will be called automatically when the final reference to the 246 * #GDebugControllerDBus is dropped. You may want to call it explicitly to know 247 * when the controller has been fully removed from the bus, or to break 248 * reference count cycles. 249 * 250 * Calling this method from within a #GDebugControllerDBus::authorize signal 251 * handler will cause a deadlock and must not be done. 252 * 253 * Since: 2.72 254 */ 255 public void stop() 256 { 257 g_debug_controller_dbus_stop(gDebugControllerDBus); 258 } 259 260 /** 261 * Emitted when a D-Bus peer is trying to change the debug settings and used 262 * to determine if that is authorized. 263 * 264 * This signal is emitted in a dedicated worker thread, so handlers are 265 * allowed to perform blocking I/O. This means that, for example, it is 266 * appropriate to call `polkit_authority_check_authorization_sync()` to check 267 * authorization using polkit. 268 * 269 * If %FALSE is returned then no further handlers are run and the request to 270 * change the debug settings is rejected. 271 * 272 * Otherwise, if %TRUE is returned, signal emission continues. If no handlers 273 * return %FALSE, then the debug settings are allowed to be changed. 274 * 275 * Signal handlers must not modify @invocation, or cause it to return a value. 276 * 277 * The default class handler just returns %TRUE. 278 * 279 * Params: 280 * invocation = A #GDBusMethodInvocation. 281 * 282 * Returns: %TRUE if the call is authorized, %FALSE otherwise. 283 * 284 * Since: 2.72 285 */ 286 gulong addOnAuthorize(bool delegate(DBusMethodInvocation, DebugControllerDBus) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 287 { 288 return Signals.connect(this, "authorize", dlg, connectFlags ^ ConnectFlags.SWAPPED); 289 } 290 }